<template>
  <div ref="editorContainer" class="editor-container"></div>
</template>
<script lang="ts">
export default {
  name: 'ShellEditor',
};
</script>
<script lang="ts" setup>
import { onMounted, useTemplateRef, watch, type Ref } from 'vue';
import prettier from 'prettier/standalone';
import prettierPluginBabel from 'prettier/plugins/babel';
import prettierPluginEstree from 'prettier/plugins/estree';
import * as monaco from 'monaco-editor';
const props = defineProps({
  modelValue: String,
  language: {
    type: String,
    default: 'shell',
  },
  theme: {
    type: String,
    default: 'vs',
  },
});
const emits = defineEmits(['update:modelValue']);
const editorContainer = useTemplateRef('editorContainer') as Ref<HTMLElement>;
const toFormatLanuage = async (value: string, type: string) => {
  try {
    return prettier.format(value, {
      parser: type,
      plugins: [prettierPluginBabel, prettierPluginEstree], // 根据需要添加
      semi: true,
      trailingComma: 'all',
      singleQuote: true,
      printWidth: 80,
      tabWidth: 2,
    });
  } catch (error) {
    console.error('Error formatting code:', error);
  }
};
let editor: monaco.editor.IStandaloneCodeEditor | undefined;
onMounted(() => {
  editor = monaco.editor.create(editorContainer.value, {
    value: props.modelValue,
    language: props.language,
    minimap: {
      enabled: true,
    },
    colorDecorators: true, //颜色装饰器
    readOnly: false, //是否开启已读功能
    theme: 'vs-dark', //主题
    // 默认值为false
    automaticLayout: true,
  });

  editor.addAction({
    id: 'format.json',
    label: '格式化',
    contextMenuGroupId: 'navigation',
    contextMenuOrder: 1,
    keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyA],
    run: async () => {
      // JSON代码格式化
      const data: string | undefined = (await toFormatLanuage(editor!.getValue(), 'css')) || '';
      editor!.setValue(data);
    },
  });

  editor.onDidChangeModelContent((event) => {
    const newValue = editor?.getValue();
    emits('update:modelValue', newValue);
  });
});

//监听 value 的变化
let initLoad = false;
watch(
  () => props.modelValue,
  (newValue: string | undefined) => {
    if (!initLoad) {
      editor?.setValue(newValue || '');
      initLoad = true;
    }
  },
  { deep: true },
);
</script>
<style>
.editor-container {
  width: 100%;
  height: 100%;
}
</style>
